package com.ruoyi.lyy.utils;

/**
 * @author YueYang
 * Created on 2025/11/13 11:11
 * @version 1.0
 * 坐标工具类 计算两个经纬度之间的距离
 */
public class CoordinateUtils {
    /**
     * 地球半径（单位：千米）
     */
    private static final double EARTH_RADIUS = 6371;

    /**
     * 计算两个经纬度坐标点之间的距离 （默认单位：千米）
     *
     * @param lat1 第一个点的纬度
     * @param lng1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lng2 第二个点的经度
     * @return 距离（单位：千米）
     */
    public static double distance(double lat1, double lng1, double lat2, double lng2) {
        //调用重载方法 传递默认单位
        return distance(lat1, lng1, lat2, lng2, "km");
    }

    /**
     * 计算两个经纬度坐标点之间的距离
     * 需要自己传递单位
     *
     * @param lat1 第一个点的纬度
     * @param lng1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lng2 第二个点的经度
     * @param unit 单位："km" 为千米，"m" 为米
     * @return 距离
     */
    public static double distance(double lat1, double lng1, double lat2, double lng2, String unit) {
        // 将经纬度从度转换为弧度
        double radLat1 = Math.toRadians(lat1);
        double radLng1 = Math.toRadians(lng1);
        double radLat2 = Math.toRadians(lat2);
        double radLng2 = Math.toRadians(lng2);

        // 计算两点间的纬度差和经度差
        double dLat = radLat2 - radLat1;
        double dLng = radLng2 - radLng1;

        // 使用 Haversine 公式
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(radLat1) * Math.cos(radLat2) *
                        Math.sin(dLng / 2) * Math.sin(dLng / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        // 计算距离（单位：千米）
        double distanceKm = EARTH_RADIUS * c;

        // 根据单位返回结果
        if ("m".equalsIgnoreCase(unit)) {
            return distanceKm * 1000;
        } else {
            return distanceKm;
        }
    }

    /**
     * 计算距离（返回单位为米）
     *
     * @param lat1 第一个点的纬度
     * @param lng1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lng2 第二个点的经度
     * @return 距离（单位：米）
     */
    public static double distanceInMeter(double lat1, double lng1, double lat2, double lng2) {
        return distance(lat1, lng1, lat2, lng2, "m");
    }

    /**
     * 计算距离（返回单位为千米）
     *
     * @param lat1 第一个点的纬度
     * @param lng1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lng2 第二个点的经度
     * @return 距离（单位：千米）
     */
    public static double distanceInKm(double lat1, double lng1, double lat2, double lng2) {
        return distance(lat1, lng1, lat2, lng2, "km");
    }

}
